CDK PipelinesでLambdaをデプロイする時にCodeBuildでdockerのエラーが出る(Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?)
「CDK PipelinesのCodeBuild上で、cdk synthやDocker関係のエラーが出たらpipelines.CodePipeline
のdockerEnabledForSynth
とdockerEnabledForSelfMutation
がtrue
になっていることを確認しよう」
# エラーメッセージ [Container]Running command npx cdk synth Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? docker exited with status 1 [Container] Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: npx cdk synth. Reason: exit status 1
Using bundled file assets aws-cdk-lib.pipelines module · AWS CDK
事象
CDK PipelinesでLambdaのスタックをデプロイしようとしていました。 しかし、CDK Pipelines上のCodeBuildで以下のエラーがでます。(エラーメッセージは上記)
Lambdaスタックの単体でのデプロイは成功します。
エラー発生時のコード
#!/usr/bin/env node import 'source-map-support/register'; import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; import * as codecommit from 'aws-cdk-lib/aws-codecommit'; import * as pipelines from 'aws-cdk-lib/pipelines'; import * as lambda from 'aws-cdk-lib/aws-lambda'; import * as nodeLambda from 'aws-cdk-lib/aws-lambda-nodejs'; import * as path from 'path'; const app = new cdk.App(); class LambdaStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); new nodeLambda.NodejsFunction(this, 'NodejsFunction', { entry: path.join(__dirname, '../lambda/index.js'), handler: 'handler', runtime: lambda.Runtime.NODEJS_16_X, timeout: cdk.Duration.seconds(120), }); } } class DeployStage extends cdk.Stage { constructor(scope: Construct, id: string, props: cdk.StageProps) { super(scope, id, props); new LambdaStack(this, 'LambdaStack', {}); } } class PipelinesStack extends cdk.Stack { constructor(scope: Construct, id: string, porps?: cdk.StackProps) { super(scope, id); const repository = codecommit.Repository.fromRepositoryName(this, 'Repository', 'cdk-pipelines-sample'); const source = pipelines.CodePipelineSource.codeCommit(repository, 'main'); const pipeline = new pipelines.CodePipeline(this, 'Pipeline', { synth: new pipelines.ShellStep('Synth', { input: source, commands: ['npm ci', 'npm run build', 'npx cdk synth'], }), }); pipeline.addStage(new DeployStage(this, 'Test', {})); } } new PipelinesStack(app, "CdkPipelineStack")
原因
Lambdaのコードをデプロイするために、スクリプト等を1つのZIPファイルにする(バンドル)の処理が実行されます。 その際に、Dockerが使用されます。
この処理をCodeBuild上で行うために、CodeBuild上でDockerを実行する必要があります。
しかし、CodeBuild上で特権モードが有効(デフォルト無効)になっていない場合Dockerを起動しようとするとエラーになります。
CDKPipelinesで作成したCodeBuildを見てみると、特権モードが無効になっています。
対策
CodeBuildの特権モードを有効になるように、CDKPipelineのプロパティにdockerEnabledForSynth: true
を追加します。
CDKのドキュメント上では以下に、記載があります。
Using bundled file assets aws-cdk-lib.pipelines module · AWS CDK
#!/usr/bin/env node import 'source-map-support/register'; import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; import * as codecommit from 'aws-cdk-lib/aws-codecommit'; import * as pipelines from 'aws-cdk-lib/pipelines'; import * as lambda from 'aws-cdk-lib/aws-lambda'; import * as nodeLambda from 'aws-cdk-lib/aws-lambda-nodejs'; import * as path from 'path'; const app = new cdk.App(); class LambdaStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); new nodeLambda.NodejsFunction(this, 'NodejsFunction', { entry: path.join(__dirname, '../lambda/index.js'), handler: 'handler', runtime: lambda.Runtime.NODEJS_16_X, timeout: cdk.Duration.seconds(120), }); } } class DeployStage extends cdk.Stage { constructor(scope: Construct, id: string, props: cdk.StageProps) { super(scope, id, props); new LambdaStack(this, 'LambdaStack', {}); } } class PipelinesStack extends cdk.Stack { constructor(scope: Construct, id: string, porps?: cdk.StackProps) { super(scope, id); const repository = codecommit.Repository.fromRepositoryName(this, 'Repository', 'cdk-pipelines-sample'); const source = pipelines.CodePipelineSource.codeCommit(repository, 'main'); const pipeline = new pipelines.CodePipeline(this, 'Pipeline', { synth: new pipelines.ShellStep('Synth', { input: source, commands: ['npm ci', 'npm run build', 'npx cdk synth'], }), dockerEnabledForSynth: true }); pipeline.addStage(new DeployStage(this, 'Test', {})); } } new PipelinesStack(app, "CdkPipelineStack")
ちなみに、CDK Pipelines上でDocker image Assetsを使う場合は、dockerEnabledForSelfMutation: true
も追加する必要があります。
おわりに
CDK PipelinesでLambdaをデプロイする際に出たエラーに関してでした。
cdk.devのSlackでちょうど同じエラー出ている人を見つけられたので、Google検索で見つからない場合はcdk.devのSlack内検索してみるのもいいかもしれません。
以上、AWS事業本部の佐藤(@chari7311)でした。